<template>
  <div class="files-page">
    <div class="page-container">
      <div class="page-header">
        <h2 class="page-title">文件管理</h2>
        <div class="header-actions">
          <el-upload
            ref="uploadRef"
            :auto-upload="false"
            :on-change="handleFileChange"
            :show-file-list="false"
            multiple
          >
            <el-button type="primary">
              <el-icon><Upload /></el-icon>
              上传文件
            </el-button>
          </el-upload>
          <el-button @click="fetchFiles">
            <el-icon><Refresh /></el-icon>
            刷新
          </el-button>
        </div>
      </div>

      <!-- 上传对话框 -->
      <el-dialog v-model="showUploadDialog" title="上传文件" width="600px">
        <el-form :model="uploadForm" label-width="100px">
          <el-form-item label="文件描述">
            <el-input
              v-model="uploadForm.description"
              type="textarea"
              :rows="3"
              placeholder="请输入文件描述（可选）"
            />
          </el-form-item>

          <el-form-item label="文件列表">
            <div class="file-list">
              <div
                v-for="(file, index) in uploadFiles"
                :key="index"
                class="file-item"
              >
                <div class="file-info">
                  <el-icon class="file-icon"><Document /></el-icon>
                  <span class="file-name">{{ file.name }}</span>
                  <span class="file-size">{{ formatFileSize(file.size) }}</span>
                </div>
                <el-button
                  type="danger"
                  size="small"
                  :icon="Delete"
                  circle
                  @click="removeUploadFile(index)"
                />
              </div>
            </div>
          </el-form-item>
        </el-form>

        <template #footer>
          <el-button @click="showUploadDialog = false">取消</el-button>
          <el-button
            type="primary"
            @click="handleUploadFiles"
            :loading="uploading"
            :disabled="uploadFiles.length === 0"
          >
            开始上传
          </el-button>
        </template>
      </el-dialog>

      <!-- 文件过滤器 -->
      <div class="filter-section">
        <el-row :gutter="20">
          <el-col :span="6">
            <el-input
              v-model="searchQuery"
              placeholder="搜索文件名"
              @input="handleSearch"
              clearable
            >
              <template #prefix>
                <el-icon><Search /></el-icon>
              </template>
            </el-input>
          </el-col>
          <el-col :span="4">
            <el-select v-model="fileTypeFilter" placeholder="文件类型" @change="fetchFiles" clearable>
              <el-option label="全部" value="" />
              <el-option label="文本文件" value="text" />
              <el-option label="图片文件" value="image" />
              <el-option label="压缩文件" value="archive" />
              <el-option label="其他文件" value="other" />
            </el-select>
          </el-col>
          <el-col :span="4">
            <el-select v-model="sizeFilter" placeholder="文件大小" @change="fetchFiles" clearable>
              <el-option label="全部" value="" />
              <el-option label="小于1MB" value="small" />
              <el-option label="1MB-10MB" value="medium" />
              <el-option label="大于10MB" value="large" />
            </el-select>
          </el-col>
          <el-col :span="4">
            <el-button type="primary" @click="fetchFiles">搜索</el-button>
          </el-col>
        </el-row>
      </div>

      <!-- 文件列表 -->
      <el-table
        :data="files"
        v-loading="loading"
        element-loading-text="加载中..."
        empty-text="暂无文件"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="name" label="文件名" min-width="200">
          <template #default="scope">
            <div class="file-name-cell">
              <el-icon class="file-icon">
                <Document v-if="isTextFile(scope.row.name)" />
                <Picture v-else-if="isImageFile(scope.row.name)" />
                <FolderOpened v-else-if="isArchiveFile(scope.row.name)" />
                <Document v-else />
              </el-icon>
              <span class="file-name">{{ scope.row.name }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="size" label="文件大小" width="120">
          <template #default="scope">
            {{ formatFileSize(scope.row.size) }}
          </template>
        </el-table-column>
        <el-table-column prop="content_type" label="文件类型" width="120" />
        <el-table-column prop="description" label="描述" show-overflow-tooltip />
        <el-table-column prop="created_at" label="上传时间" width="180">
          <template #default="scope">
            {{ formatDateTime(scope.row.created_at) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200">
          <template #default="scope">
            <div class="table-actions">
              <el-button size="small" @click="downloadFile(scope.row)">
                下载
              </el-button>
              <el-button size="small" @click="handlePreviewFile(scope.row)">
                预览
              </el-button>
              <el-button size="small" type="danger" @click="deleteFile(scope.row)">
                删除
              </el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>

      <!-- 批量操作 -->
      <div v-if="selectedFiles.length > 0" class="batch-actions">
        <div class="selection-info">
          已选择 {{ selectedFiles.length }} 个文件
        </div>
        <div class="action-buttons">
          <el-button @click="batchDownload">批量下载</el-button>
          <el-button type="danger" @click="batchDelete">批量删除</el-button>
        </div>
      </div>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.size"
          :total="pagination.total"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>

      <!-- 文件预览对话框 -->
      <el-dialog v-model="showPreviewDialog" :title="previewFile?.name" width="80%">
        <div class="file-preview">
          <div v-if="previewLoading" class="preview-loading">
            <el-skeleton :rows="10" animated />
          </div>
          <div v-else-if="previewContent">
            <pre v-if="isTextFile(previewFile?.name)" class="text-preview">{{ previewContent }}</pre>
            <img
              v-else-if="isImageFile(previewFile?.name)"
              :src="previewContent"
              class="image-preview"
              alt="图片预览"
            />
            <div v-else class="binary-preview">
              <el-alert
                title="无法预览"
                type="warning"
                description="此文件类型不支持预览，请下载后查看"
                show-icon
                :closable="false"
              />
            </div>
          </div>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Upload,
  Refresh,
  Search,
  Document,
  Picture,
  FolderOpened,
  Delete
} from '@element-plus/icons-vue'
import { fileApi } from '../api'

// 数据状态
const loading = ref(false)
const uploading = ref(false)
const files = ref([])
const selectedFiles = ref([])
const showUploadDialog = ref(false)
const showPreviewDialog = ref(false)
const previewFile = ref(null)
const previewContent = ref('')
const previewLoading = ref(false)

// 搜索和过滤
const searchQuery = ref('')
const fileTypeFilter = ref('')
const sizeFilter = ref('')

// 分页
const pagination = reactive({
  page: 1,
  size: 20,
  total: 0
})

// 上传相关
const uploadRef = ref()
const uploadFiles = ref([])
const uploadForm = reactive({
  description: ''
})

// 获取文件列表
const fetchFiles = async () => {
  loading.value = true
  try {
    const params = {
      page: pagination.page,
      size: pagination.size,
      search: searchQuery.value || undefined,
      file_type: fileTypeFilter.value || undefined,
      size_filter: sizeFilter.value || undefined
    }

    const response = await fileApi.getFiles(params)
    files.value = response.data?.items || []
    pagination.total = response.data?.total || 0
  } catch (error) {
    console.error('获取文件列表失败:', error)
    ElMessage.error('获取文件列表失败')
  } finally {
    loading.value = false
  }
}

// 搜索处理
const handleSearch = () => {
  pagination.page = 1
  fetchFiles()
}

// 分页处理
const handleSizeChange = (size) => {
  pagination.size = size
  pagination.page = 1
  fetchFiles()
}

const handleCurrentChange = (page) => {
  pagination.page = page
  fetchFiles()
}

// 选择处理
const handleSelectionChange = (selection) => {
  selectedFiles.value = selection
}

// 文件上传处理
const handleFileChange = (file) => {
  uploadFiles.value.push(file.raw)
  showUploadDialog.value = true
}

const removeUploadFile = (index) => {
  uploadFiles.value.splice(index, 1)
}

const handleUploadFiles = async () => {
  if (uploadFiles.value.length === 0) {
    ElMessage.warning('请选择要上传的文件')
    return
  }

  uploading.value = true
  try {
    const formData = new FormData()

    uploadFiles.value.forEach(file => {
      formData.append('files', file)
    })

    if (uploadForm.description) {
      formData.append('description', uploadForm.description)
    }

    await fileApi.uploadFile(formData, {
      onUploadProgress: (progressEvent) => {
        const percentCompleted = Math.round(
          (progressEvent.loaded * 100) / progressEvent.total
        )
        // 可以在这里显示上传进度
        console.log(`上传进度: ${percentCompleted}%`)
      }
    })

    ElMessage.success('文件上传成功')
    showUploadDialog.value = false
    uploadFiles.value = []
    uploadForm.description = ''
    fetchFiles()
  } catch (error) {
    console.error('文件上传失败:', error)
    ElMessage.error('文件上传失败')
  } finally {
    uploading.value = false
  }
}

// 下载文件
const downloadFile = async (file) => {
  try {
    const response = await fileApi.downloadFile(file.id)

    // 创建下载链接
    const blob = new Blob([response.data])
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = file.name
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
  } catch (error) {
    console.error('下载文件失败:', error)
    ElMessage.error('下载文件失败')
  }
}

// 预览文件
const handlePreviewFile = async (file) => {
  previewFile.value = file
  showPreviewDialog.value = true
  previewLoading.value = true

  try {
    if (isTextFile(file.name)) {
      const response = await fileApi.previewFile(file.id)
      previewContent.value = response.data?.content || ''
    } else if (isImageFile(file.name)) {
      const response = await fileApi.downloadFile(file.id)
      const url = URL.createObjectURL(response.data)
      previewContent.value = url
    } else {
      previewContent.value = null
    }
  } catch (error) {
    console.error('预览文件失败:', error)
    ElMessage.error('预览文件失败')
    previewContent.value = null
  } finally {
    previewLoading.value = false
  }
}

// 删除文件
const deleteFile = async (file) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除文件"${file.name}"吗？此操作不可撤销。`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    await fileApi.deleteFile(file.id)
    ElMessage.success('文件删除成功')
    fetchFiles()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除文件失败:', error)
      ElMessage.error('删除文件失败')
    }
  }
}

// 批量下载
const batchDownload = async () => {
  // TODO: 实现批量下载功能
  ElMessage.info('批量下载功能开发中')
}

// 批量删除
const batchDelete = async () => {
  try {
    await ElMessageBox.confirm(
      `确定要删除选中的 ${selectedFiles.value.length} 个文件吗？此操作不可撤销。`,
      '确认批量删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    const fileIds = selectedFiles.value.map(file => file.id)
    await fileApi.batchDelete(fileIds)
    ElMessage.success('批量删除成功')
    selectedFiles.value = []
    fetchFiles()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('批量删除失败:', error)
      ElMessage.error('批量删除失败')
    }
  }
}

// 文件类型判断
const isTextFile = (filename) => {
  const textExtensions = ['.txt', '.md', '.json', '.xml', '.yaml', '.yml', '.log', '.csv']
  const extension = filename.toLowerCase().substring(filename.lastIndexOf('.'))
  return textExtensions.includes(extension)
}

const isImageFile = (filename) => {
  const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp']
  const extension = filename.toLowerCase().substring(filename.lastIndexOf('.'))
  return imageExtensions.includes(extension)
}

const isArchiveFile = (filename) => {
  const archiveExtensions = ['.zip', '.rar', '.7z', '.tar', '.gz', '.bz2']
  const extension = filename.toLowerCase().substring(filename.lastIndexOf('.'))
  return archiveExtensions.includes(extension)
}

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (!bytes) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 格式化日期时间
const formatDateTime = (dateTime) => {
  if (!dateTime) return '-'
  return new Date(dateTime).toLocaleString('zh-CN')
}

// 页面加载时获取数据
onMounted(() => {
  fetchFiles()
})
</script>

<style scoped>
.files-page {
  padding: 0;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.header-actions {
  display: flex;
  gap: 12px;
}

.filter-section {
  margin-bottom: 20px;
}

.file-list {
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid #e6e6e6;
  border-radius: 4px;
  padding: 10px;
}

.file-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px;
  border-bottom: 1px solid #f0f0f0;
}

.file-item:last-child {
  border-bottom: none;
}

.file-info {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
}

.file-icon {
  color: #409eff;
}

.file-name {
  font-weight: 500;
  color: #303133;
}

.file-size {
  font-size: 12px;
  color: #909399;
}

.file-name-cell {
  display: flex;
  align-items: center;
  gap: 8px;
}

.table-actions {
  display: flex;
  gap: 8px;
}

.batch-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 20px;
  padding: 16px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.selection-info {
  color: #606266;
  font-weight: 500;
}

.action-buttons {
  display: flex;
  gap: 12px;
}

.pagination-container {
  margin-top: 20px;
  text-align: center;
}

.file-preview {
  max-height: 600px;
  overflow: auto;
}

.preview-loading {
  padding: 20px;
}

.text-preview {
  background-color: #f5f7fa;
  padding: 16px;
  border-radius: 4px;
  white-space: pre-wrap;
  word-break: break-all;
  font-family: monospace;
  font-size: 14px;
  line-height: 1.5;
  max-height: 500px;
  overflow-y: auto;
}

.image-preview {
  max-width: 100%;
  max-height: 500px;
  object-fit: contain;
}

.binary-preview {
  text-align: center;
  padding: 40px;
}
</style>
